package utils;

import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

public final class ExcelResponse {
    private HttpServletResponse response;
    private static final int BUFFER_SIZE = 8192;
    private static final String ENCODING = "UTF-8";
    public static final String DISPOSITION_INLINE = "inline";
    public static final String DISPOSITION_ATTACHMENT = "attachment";
    public static final String CONTENT_TYPE_XML = "text/xml";
    public static final String CONTENT_TYPE_HTML = "text/html";
    public static final String CONTENT_TYPE_TEXT = "text/plain";
    public static final String CONTENT_TYPE_JSON = "application/json";
    public static final String CONTENT_TYPE_STYLE = "text/css";
    public static final String CONTENT_TYPE_SCRIPT = "text/javascript";
    public static final String CONTENT_TYPE_IMAGE = "image/png";
    public static final String CONTENT_TYPE_IMAGE_PNG = "image/png";
    public static final String CONTENT_TYPE_IMAGE_JPG = "image/jpeg";
    public static final String CONTENT_TYPE_IMAGE_GIF = "image/gif";
    public static final String CONTENT_TYPE_IMAGE_TIFF = "image/tiff";
    public static final String CONTENT_TYPE_FILE = "application/octet-stream";
    private static Map<String, String> ctmap = null;

    @Deprecated
    public ExcelResponse(HttpServletResponse resp)
    {
        this.response = resp;
    }

    public void setStatus(int code)
    {
        this.response.reset();
        this.response.setStatus(code);
    }

    public void setStatus(int code, String text) {
        try {
            this.response.reset();
            this.response.setStatus(code);
            this.response.setContentType("text/plain");
            this.response.setCharacterEncoding("utf-8");
            PrintWriter writer = this.response.getWriter();
            writer.write(text);
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void renderHtml(String html)
    {
        renderHtml(html, false);
    }

    public void renderHtml(String html, boolean tag) {
        try {
            this.response.reset();
            this.response.setContentType("text/html");
            this.response.setCharacterEncoding("utf-8");
            PrintWriter writer = this.response.getWriter();
            if (tag) {
                writer.println("<!DOCTYPE html>\r\n");
                writer.println("<html>\r\n");
                writer.println("<head>\r\n");
                writer.println("\t<title></title>\r\n");
                writer.println("\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\r\n");
                writer.println("</head>\r\n");
                writer.println("<body>\r\n");
                writer.println("\t" + html + "\r\n");
                writer.println("</body>\r\n");
                writer.println("</html>\r\n");
            }
            else {
                writer.println(html);
            }
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void renderText(String text)
    {
        try {
            this.response.reset();
            this.response.setContentType("text/plain");
            this.response.setCharacterEncoding("utf-8");
            PrintWriter writer = this.response.getWriter();
            writer.write(text);
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void renderJson(String json)
    {
        try {
            this.response.reset();
            this.response.setContentType("application/json");
            this.response.setCharacterEncoding("utf-8");
            PrintWriter writer = this.response.getWriter();
            writer.write(json);
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void renderStyle(String css)
    {
        try {
            this.response.reset();
            this.response.setContentType("text/css");
            this.response.setCharacterEncoding("utf-8");
            PrintWriter writer = this.response.getWriter();
            writer.write(css);
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void renderScript(String js)
    {
        try {
            this.response.reset();
            this.response.setContentType("text/javascript");
            this.response.setCharacterEncoding("utf-8");
            PrintWriter writer = this.response.getWriter();
            writer.write(js);
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void renderImage(String path)
    {
        String ctype = mimeType(path);
        FileInputStream fis = null;
        try { fis = new FileInputStream(path); } catch (Exception localException) {
        }
        renderImage(fis, ctype); }

    public void renderImage(File file) {
        String ctype = mimeType(file.getName());
        FileInputStream fis = null;
        try { fis = new FileInputStream(file); } catch (Exception localException) {
        }
        renderImage(fis, ctype);
    }

    public void renderImage(byte[] data) {
        renderImage(new ByteArrayInputStream(data), null); }

    public void renderImage(byte[] data, String ctype) {
        renderImage(new ByteArrayInputStream(data), ctype);
    }

    public void renderImage(InputStream stream) {
        renderImage(stream, null); }

    public void renderImage(InputStream stream, String ctype) {
        BufferedOutputStream bfos = null;
        ServletOutputStream srvos = null;
        try {
            if (StringUtils.isBlank(ctype)) {
                ctype = "image/jpeg";
            }
            this.response.reset();
            this.response.setBufferSize(8192);
            this.response.setContentType(ctype);
            this.response.setHeader("Content-Disposition", "inline; filename=download.jpg");

            srvos = this.response.getOutputStream();
            bfos = new BufferedOutputStream(srvos);
            int read = 0;
            byte[] buffer = new byte[8192];
            while ((read = stream.read(buffer, 0, buffer.length)) != -1) {
                bfos.write(buffer, 0, read);
            }
            srvos.flush();
        }
        catch (Exception localException2) {
            localException2.printStackTrace();
        }
        finally {
            try {
                if (bfos != null) {
                    bfos.close();
                }
                if (srvos != null) {
                    srvos.close();
                }
                if (stream != null)
                    stream.close();
            }
            catch (Exception localException3)
            {
            }
        }
    }

    public void renderFile() {
        String path = null;
        renderFile(path, null, null); }

    public void renderFile(String path) {
        renderFile(new File(path), null, null); }

    public void renderFile(String path, String name) {
        renderFile(new File(path), name, null); }

    public void renderFile(String path, String name, String disp) {
        renderFile(new File(path), name, disp);
    }

    public void renderFile(File file) {
        renderFile(file, null, null); }

    public void renderFile(File file, String name) {
        renderFile(file, name, null); }

    public void renderFile(File file, String name, String disp) {
        if ((file == null) || (!(file.exists()))) {
            renderHtml("<h3 style='color:red;'>文件不存在！</h3>", true);
            return;
        }
        if (StringUtils.isBlank(name)) {
            name = file.getName();
        }
        FileInputStream fis = null;
        try { fis = new FileInputStream(file); } catch (Exception err) {
            fis = null; }
        renderFile(fis, name, disp);
    }

    public void renderFile(byte[] data, String name) {
        renderFile(new ByteArrayInputStream(data), name, null); }

    public void renderFile(byte[] data, String name, String disp) {
        renderFile(new ByteArrayInputStream(data), name, disp);
    }

    public void renderFile(InputStream stream, String name) {
        renderFile(stream, name, null); }

    public void renderFile(InputStream stream, String name, String disp) {
        if (StringUtils.isBlank(name)) {
            name = "未知文件";
        }
        if (StringUtils.isBlank(disp)) {
            disp = "attachment";
        }
        if (stream == null) {
            renderHtml("<h3 style='color:red;'>文件不存在！</h3>", true);
            return;
        }
        BufferedOutputStream bfos = null;
        ServletOutputStream srvos = null;
        try {
            String mtype = mimeType(name);

            this.response.reset();
            this.response.setBufferSize(8192);
            this.response.setContentType(mtype);
            this.response.setContentLength(stream.available());
            this.response.setHeader("Content-Disposition", disp + "; filename=" + URLEncoder.encode(name, "UTF-8"));

            srvos = this.response.getOutputStream();
            bfos = new BufferedOutputStream(srvos);
            int read = 0;
            byte[] buffer = new byte[8192];
            while ((read = stream.read(buffer, 0, buffer.length)) != -1) {
                bfos.write(buffer, 0, read);
            }
            srvos.flush();
        }
        catch (Exception localException2) {
            localException2.printStackTrace();
        }
        finally {
            try {
                if (bfos != null) {
                    bfos.close();
                }
                if (srvos != null) {
                    srvos.close();
                }
                if (stream != null)
                    stream.close();
            }
            catch (Exception localException3)
            {
            }
        }
    }

    public void prepareFile(String name) {
        prepareFile(name, null, 0);
    }

    public void prepareFile(String name, String disp) {
        prepareFile(name, disp, 0);
    }

    public void prepareFile(String name, String disp, int length) {
        try {
            this.response.reset();
            this.response.setBufferSize(8192);
            this.response.setContentType(mimeType(name));
            if (length > 0) {
                this.response.setContentLength(length);
            }
            if (StringUtils.isBlank(disp)) {
                disp = "attachment";
            }
            this.response.setHeader("Content-Disposition", disp + "; filename=" + URLEncoder.encode(name, "UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void status(HttpServletResponse resp, int code)
    {
        status(resp, code, null);
    }

    public static void status(HttpServletResponse resp, int code, String text) {
        try {
            resp.reset();
            resp.setStatus(code);
            resp.setContentType("text/plain");
            resp.setCharacterEncoding("UTF-8");
            if (StringUtils.isNotBlank(text)) {
                PrintWriter writer = resp.getWriter();
                writer.write(text);
                writer.flush();
                writer.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void disposition(HttpServletResponse resp, String name, String disp, int length)
    {
        try {
            if (StringUtils.isBlank(name)) {
                name = "";
                if (StringUtils.isBlank(disp)) {
                    disp = "inline";
                }
            }
            if (StringUtils.isBlank(disp)) {
                disp = "attachment";
            }
            resp.reset();
            resp.setBufferSize(8192);
            resp.setContentType(mimeType(name));
            if (length > 0) {
                resp.setContentLength(length);
            }
            resp.setHeader("Access-Control-Allow-Origin", "*");
            resp.setHeader("Content-Disposition", disp + "; filename=" + URLEncoder.encode(name, "UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void write(HttpServletResponse resp, String ctype, String text)
    {
        try {
            resp.reset();
            resp.setContentType(ctype);
            resp.setCharacterEncoding("UTF-8");
            PrintWriter writer = resp.getWriter();
            writer.write(text);
            writer.flush();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void write(HttpServletResponse resp, String ctype, byte[] data)
    {
        write(resp, ctype, data, null, null);
    }

    public static void write(HttpServletResponse resp, String ctype, byte[] data, String name) {
        write(resp, ctype, data, name, null);
    }

    public static void write(HttpServletResponse resp, String ctype, byte[] data, String name, String disp) {
        ByteArrayInputStream bais = new ByteArrayInputStream(data);
        write(resp, ctype, bais, name, disp);
    }

    public static void write(HttpServletResponse resp, String ctype, File file)
    {
        write(resp, ctype, file, file.getName(), null);
    }

    public static void write(HttpServletResponse resp, String ctype, File file, String name) {
        if (StringUtils.isBlank(name)) {
            name = file.getName();
        }
        write(resp, ctype, file, name, null);
    }

    public static void write(HttpServletResponse resp, String ctype, File file, String name, String disp) {
        if (StringUtils.isBlank(name))
            name = file.getName();
        try
        {
            write(resp, ctype, new FileInputStream(file), name, disp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void write(HttpServletResponse resp, String ctype, InputStream stream)
    {
        write(resp, ctype, stream, null, null);
    }

    public static void write(HttpServletResponse resp, String ctype, InputStream stream, String name) {
        write(resp, ctype, stream, name, null);
    }

    public static void write(HttpServletResponse resp, String ctype, InputStream stream, String name, String disp) {
        BufferedOutputStream bfos = null;
        ServletOutputStream srvos = null;
        try {
            if (StringUtils.isBlank(name)) {
                name = "";
                if (StringUtils.isBlank(disp)) {
                    disp = "inline";
                }
            }
            if (StringUtils.isBlank(disp)) {
                disp = "attachment";
            }
            resp.reset();
            resp.setBufferSize(8192);
            resp.setContentType(mimeType(name));
            resp.setHeader("Content-Disposition", disp + "; filename=" + URLEncoder.encode(name, "UTF-8"));
            srvos = resp.getOutputStream();
            bfos = new BufferedOutputStream(srvos);
            int read = 0;
            byte[] buffer = new byte[8192];
            while ((read = stream.read(buffer, 0, buffer.length)) != -1) {
                bfos.write(buffer, 0, read);
            }
            srvos.flush();
        }
        catch (Exception localException2) {
            localException2.printStackTrace();
        }
        finally {
            try {
                if (bfos != null) {
                    bfos.close();
                }
                if (srvos != null) {
                    srvos.close();
                }
                if (stream != null)
                    stream.close();
            }
            catch (Exception localException3)
            {
            }
        }
    }

    private static String mimeType(String ext)
    {
        if (ext == null) {
            ext = "";
        }
        ext = ext.toLowerCase().trim();
        int idx = ext.lastIndexOf(".");
        if (idx > 0) {
            ext = ext.substring(idx);
        }
        if (ctmap == null) {
            ctmap = new HashMap();
            ctmap.put("*", "application/octet-stream");
            ctmap.put(".apk", "application/vnd.android.package-archive");
            ctmap.put(".bmp", "application/x-bmp");
            ctmap.put(".gif", "image/gif");
            ctmap.put(".jpg", "image/jpeg");
            ctmap.put(".jpeg", "image/jpeg");
            ctmap.put(".tif", "image/tiff");
            ctmap.put(".tiff", "image/tiff");
            ctmap.put(".png", "image/png");
            ctmap.put(".doc", "application/msword");
            ctmap.put(".docx", "application/msword");
            ctmap.put(".xls", "application/vnd.ms-excel");
            ctmap.put(".xlsx", "application/vnd.ms-excel");
            ctmap.put(".pdf", "application/pdf");
            ctmap.put(".txt", "text/plain");
            ctmap.put(".htm", "text/html");
            ctmap.put(".html", "text/html");
            ctmap.put(".xml", "text/xml");
        }
        if (ctmap.containsKey(ext)) {
            return ((String)ctmap.get(ext));
        }
        return "application/octet-stream";
    }
}